/*
 * cFuego.cpp
 *
 *  Created on: Nov 8, 2014
 *      Author: root
 */

#include "cFuego.h"
#include "../objetosGrilla.h"
#include "../manejadorGrilla.h"
#include "../clasesAuxiliares/SocketCommunication.h"
#include "../clasesAuxiliares/envioAlCliente.h"
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <iostream>

const int GRILLA_WIDTH = 64;
const int GRILLA_HEIGHT = 48;

const int FIJO = -1;
const int IZQUIERDA = 0;
const int DERECHA = 1;
const int SUBIENDO_ESCALERA = 2;
const int SALTANDO_IZQUERDA = 5;
const int SALTANDO_DERECHA = 6;

cFuego::cFuego(){
	this->fin = true;
	this->x = 0;
	this->y = 0;
	this->height = 2;
	this->witdh = 2;
}


cFuego::~cFuego() {
	if(this->fin ==  false)
	{
		this->fin = true;
		std::cout <<"MUERE FUEGO: " << this->id << " (" << this->x << " , " << this->y << ")"<< std::endl;
		envioAlCliente::envioBorrarPersonaje(this->id, this->socket_J1, this->socket_J2);
	}
}


void cFuego::InicializarFijo(manejadorGrilla &grilla, int x, int y,int id , SocketCommunication *socket_J1, SocketCommunication *socket_J2){
	sprintf(this->id, "fue_%d", id);
	this->height = 2;
	this->witdh = 2;
	this->type = objetosGrilla::getTypeFuego();
	this->sentido = 0;
	this->fin = false;
	this->saltoMovimiento = 0;
	this->nextRand = 1;
	this->socket_J1 = socket_J1;
	this->socket_J2 = socket_J2;
	this->x = x;
	this->y = y;
	this->sentido = FIJO;

	envioAlCliente::envioCreacion(this->id, this->socket_J1, this->socket_J2, this->x, this->y);
}

void cFuego::Desactivar()
{
	if(this->fin ==  false)
	{
		this->fin =  true;
		envioAlCliente::envioBorrarPersonaje(this->id, this->socket_J1, this->socket_J2);
	}
}

void cFuego::InicializarAleatorio(manejadorGrilla &grilla,int id , SocketCommunication *socket_J1, SocketCommunication *socket_J2)
{
	sprintf(this->id, "fue_%d", id);
	this->height = 2;
	this->witdh = 2;
	this->type = objetosGrilla::getTypeFuego();
	this->sentido = 0;
	this->fin = false;
	this->saltoMovimiento = 0;
	this->nextRand = 1;
	this->socket_J1 = socket_J1;
	this->socket_J2 = socket_J2;
	this->y =43;
	if (this->getRandom() == 0)
	{
		this->sentido = DERECHA;
		this->x = 33;
	}
	else
	{
		this->sentido = IZQUIERDA;
		this->x = 29;
	}

	envioAlCliente::envioCreacion(this->id, this->socket_J1, this->socket_J2, this->x, this->y);
}

void cFuego::mover(manejadorGrilla &grilla)
{
	if(this->sentido == FIJO)
		return;

	switch (this->sentido) {
	case IZQUIERDA:
	{
		//si se va de la pantalla y esta en la ultima linea termina
		if(this->x - 1< 0  && this->y < 17)
		{
			this->fin = true;
			envioAlCliente::envioBorrarPersonaje(this->id, this->socket_J1, this->socket_J2);
			return;
		}

		if (grilla.matriz[this->x - 1][this->y + 2] == 0) //evaluo si no hay piso...
		{
			if ((grilla.matriz[this->x - 5][this->y + 2] == 0) || (this->x - 5 <  0)) //esto es para darme cuenta si es un salto o termino el nivel y tiene que cambiar de sentido
			{
				this->sentido = DERECHA;
			} else {
				//tengo que saltar
				this->sentido = SALTANDO_IZQUERDA;
				this->saltoMovimiento = 1;
				this->x--;
				this->y--;
			}
		} else {
			//muevo
			this->x--;
			//despues de mover evaluo otras condiciones...


			//si no es el ultimo nivel (el de mas arriba)
			if(this->y > 17)
			{
				//si hay escalera
				if (grilla.matriz[this->x][this->y] == objetosGrilla::getTypeEscalera() 	&& grilla.matriz[this->x + 1][this->y]== objetosGrilla::getTypeEscalera())
				{
					//hago un random indicando si la bajo o no...
					if (this->getRandom() == 0)
						this->sentido = SUBIENDO_ESCALERA;  //bajo la escalera
					else
						this->sentido = IZQUIERDA;  //sigo moviendome a la izquierda
					}
			}
		}
	}
	break;
	case DERECHA:
	{
		//si sale de la pantalla en el nivel inferior
				//si se va de la pantalla
				if(this->x + 3 > GRILLA_WIDTH  && this->y < 17)
				{
					this->fin = true;
					envioAlCliente::envioBorrarPersonaje(this->id, this->socket_J1, this->socket_J2);
					return;
				}

				if (grilla.matriz[this->x + 1][this->y + 2] == 0) //evaluo si no hay piso...
				{
					if ((grilla.matriz[this->x + 8][this->y + 2] == 0 ) || (this->x + 8 >  GRILLA_WIDTH)) //esto es para darme cuenta si es un salto o termino el nivel y tiene que cambiar de sentido
					{
						this->sentido = IZQUIERDA;
					} else {
						//tengo que saltar
						this->sentido = SALTANDO_DERECHA;
						this->saltoMovimiento = 1;
						this->x++;
						this->y--;
					}
				} else {
					//muevo
					this->x++;
					//despues de mover evaluo otras condiciones...
					//si no es el ultimo nivel (el de mas arriba)
					if(this->y > 17)
					{
							//si hay escalera
							if (grilla.matriz[this->x][this->y]	== objetosGrilla::getTypeEscalera() && grilla.matriz[this->x + 1][this->y]	== objetosGrilla::getTypeEscalera()) {
								//hago un random indicando si la bajo o no...
								if (this->getRandom() == 0)
									this->sentido = SUBIENDO_ESCALERA;  //bajo la escalera
								else
									this->sentido = DERECHA;   //sigo moviendome a la izquierda
							}
					}
				}
			}
		break;
	case SUBIENDO_ESCALERA:
		{
			this->y--;
			if (grilla.matriz[this->x][this->y + 2] == objetosGrilla::getTypePiso()) //si ya llego al piso
			{
				if (this->getRandom() == 0)
					this->sentido = IZQUIERDA;
				else
					this->sentido = DERECHA;
			}
		}
		break;
	case SALTANDO_IZQUERDA:
	{
		this->saltando(IZQUIERDA);
	}
		break;
	case SALTANDO_DERECHA:
	{
		this->saltando(DERECHA);
	}
		break;
	}
}


//genera un un numero random del 1 al 10
int cFuego::getRandom() {
	this->nextRand = this->nextRand * 3 + time(NULL);
	srand(this->nextRand);

	//devuelve un numero entre 0 y 1
	return (rand() % 2);
}



void cFuego::saltando(int sentido)
{
	switch (this->saltoMovimiento) {
		case 1:
			if(sentido == IZQUIERDA)
				this->x--;
			else
				this->x++;
			this->saltoMovimiento = 2;
			break;
		case 2:
			if(sentido == IZQUIERDA)
				this->x--;
			else
				this->x++;
			this->saltoMovimiento = 3;
			break;
		case 3:
			if(sentido == IZQUIERDA)
				this->x--;
			else
				this->x++;
			this->y++;
			this->saltoMovimiento = 4;
			break;
		case 4:
			if(sentido == IZQUIERDA)
				this->x--;
			else
				this->x++;
			this->saltoMovimiento = 0;
			this->sentido = sentido;
			break;
		default:
			this->sentido = sentido;
			this->saltoMovimiento = 0;
			break;
		}
}



